﻿using System.Threading;

namespace Rsdn.Janus.VirtualForums.AnswersMe
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using BLToolkit.Data;
    using BLToolkit.Data.Linq;
    using DataModel;

    internal class AnswersMeMessage : LinearTreeMsg
    {
        private const int MaxRepeat = 5;

        public AnswersMeMessage(IServiceProvider provider)
            : base(provider)
        {
        }

        protected override void FillChildren()
        {
            // do nothing    
        }

        public void FillChildrenWithMessagesToMe()
        {
            Children = GetMessagesToMeList();

            int unreadCount = 0;
            foreach (MsgBase msg in Children)
            {
                msg.EndMapping(null);
                if (msg.IsUnread)
                {
                    unreadCount++;
                }

                // Why read & unread is different fields?
                // msg.IsRead
            }

            Unread = unreadCount;

            //return msg;
        }

        protected IQueryable<IForumMessage> GetMessages(IJanusDataContext db)
        {
            return db.Messages(m => m.ParentID != 0 && m.Parent.UserID == Config.Instance.SelfId);
        }

        public void FillCounters()
        {
            using (IJanusDataContext db = ServiceProvider.CreateDBContext())
            {
                if (!db.IsValid())
                {
                    return;
                }
                int i;
                Exception lastDbEx = null;
                for (i = 0; i < MaxRepeat; i++)
                {
                    try
                    {
                        IQueryable<IForumMessage> forumMessages = GetMessages(db);
                        RepliesCount = forumMessages.Count();
                        UnreadCount = forumMessages.Count(im => !im.IsRead);
                        break;
                    }
                    catch (DataException ex)
                    {
                        //do nothing
                        lastDbEx = ex;
                    }
                    Thread.Sleep(100);
                }
                if (i == MaxRepeat)
                {
                    throw lastDbEx;
                }

                #region SQL
//-  SQLite
//-- DECLARE @p1 Int32

//-- SET @p1 = 95947

//SELECT
//    [m].[mid] as [ID],
//    [m].[tid] as [TopicID],
//    [m].[pid] as [ParentID],
//    [m].[gid] as [ForumID],
//    [m].[Subject],
//    [m].[dte] as [Date1],
//    [m].[uid] as [UserID],
//    [m].[uclass] as [UserClass],
//    [m].[UserNick],
//    [m].[Name],
//    [m].[article_id] as [ArticleId],
//    [m].[LastModerated],
//    [m].[Closed],
//    [m].[Message],
//    [m].[IsMarked],
//    [m].[IsRead],
//    [m].[ReadReplies]
//FROM
//    [messages] [m]
//        LEFT JOIN [messages] [t1] ON [m].[pid] = [t1].[mid]
//WHERE
//    [m].[pid] <> 0 AND [t1].[uid] = @p1

                #endregion
            }
        }

        public List<MsgBase> GetMessagesToMeList()
        {
            List<MsgBase> ret = null;
            bool loadAll = true;
            SortType sort = Config.Instance.ForumSortCriteria;
            using (IJanusDataContext db = ServiceProvider.CreateDBContext())
            {
                IQueryable<IForumMessage> messages = GetMessages(db);

                messages = ForumDBHelper.AppendSortPredicate(messages, sort);

                ForumDisplayConfig displayConfig = Config.Instance.ForumDisplayConfig;
                if (displayConfig.ShowUnreadThreadsOnly)
                {
                    // messages = messages.Where(ti => !ti.Message.IsRead || ti.AnswersUnread > 0);
                }
                #region SQL
                //-- SET @p1 = 95947

                //SELECT
                //    [m].[mid] as [ID],
                //    [m].[tid] as [TopicID],
                //    [m].[pid] as [ParentID],
                //    [m].[gid] as [ForumID],
                //    [m].[Subject],
                //    [m].[dte] as [Date1],
                //    [m].[uid] as [UserID],
                //    [m].[uclass] as [UserClass],
                //    [m].[UserNick],
                //    [m].[Name],
                //    [m].[article_id] as [ArticleId],
                //    [m].[LastModerated],
                //    [m].[Closed],
                //    [m].[Message],
                //    [m].[IsMarked],
                //    [m].[IsRead],
                //    [m].[ReadReplies]
                //FROM
                //    [messages] [m]
                //        LEFT JOIN [messages] [t1] ON [m].[pid] = [t1].[mid]
                //WHERE
                //    [m].[pid] <> 0 AND [t1].[uid] = @p1
                //ORDER BY
                //    [m].[dte]... DESC
                #endregion

                if (!(loadAll || displayConfig.MaxTopicsPerForum <= 0))
                {
                    messages = messages.Take(displayConfig.MaxTopicsPerForum);
                }


                Table<IForumMessage> msgTable = db.Messages();
                ret = DataHelper.LoadMessages(ServiceProvider, messages, msgTable);
            }

            return ret;
        }

        public int UnreadCount
        {
            get
            {
                return RepliesUnread;
            }
            set
            {
                RepliesUnread = value;
            }
        }
    }
}